/////////////////////////////////////////////////////////////////////////////
// Name:        ax_menu_range.h
// Purpose:     Range menu class
// Author:      Julian Smart
// Modified by:
// Created:     2009-03-20
// RCS-ID:
// Copyright:   (c) Julian Smart
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#ifndef _AX_MENU_RANGE_H_
#define _AX_MENU_RANGE_H_

/*
 * Includes
 */

#include "ax/ax_activator.h"
#include "ax/ax_menu_modal.h"
#include "ax/ax_validator.h"
 
/*
 * Forward declarations
 */

class AxRangeActivator;
class AxRangeMenuItem;

/**
    @class AxRangeActivator

    Used by AxRangeMenuItem, as the top-level activator and also
    for submenu items.

    @category{ax}
 */

class AxRangeActivator: public AxAutoUpdateActivator
{
public:
    
    DECLARE_DYNAMIC_CLASS( AxRangeActivator )

    typedef enum 
    {
        AxRangeCommandUnknown,
        AxRangeCommandUp,
        AxRangeCommandDown,
        AxRangeCommandEnterValue,
        AxRangeCommandMain
            
    } AxRangeCommand;

public:
// Constructors

    AxRangeActivator() { Init(); }

    AxRangeActivator(
        const wxString& labelSpec,
        const wxString& descriptionSpec,
        AxRangeCommand cmd,
        AxRangeActivator* mainActivator,
        AxMenuController* controller,
        AxMenuItem* item);

    AxRangeActivator(const AxRangeActivator& activator) { Init(); Copy(activator); }

    void Init();

    void Copy(const AxRangeActivator& activator);

    virtual AxActivator* Clone() const { return new AxRangeActivator(* this); }

    /// Called when the user activates a menu item by pressing return or double-clicking
    virtual AxMenu* Activate(AxMenuController* controller, AxMenuItem* item);

    /// Create menu label or description
    virtual wxString CreateString(const wxString& spec, bool isLabel);

    /// Increase or decrease value
    virtual bool BumpValue(int by);

    /// Prompt user to enter value
    virtual bool EnterValue();

    AxRangeActivator* GetMainActivator() const { return m_mainActivator; }
    void SetMainActivator(AxRangeActivator* activator) { m_mainActivator = activator; }

    AxRangeMenuItem* GetRangeMenuItem() const;

protected:
    AxRangeActivator*   m_mainActivator;
    AxRangeCommand      m_command;
    AxMenuController*   m_controller;
    AxMenuItem*         m_item;
};

/**
    @class AxRangeMenuItem

    This is a menu item for showing and changing an integer value in a given
    range. When the value is changed, a @c wxEVT_COMMAND_SPINCTRL_UPDATED event
    is generated.

    @category{ax}
 */

class AxRangeMenuItem: public AxMenuItem
{
    DECLARE_DYNAMIC_CLASS( AxRangeMenuItem )

public:
// Constructors

    AxRangeMenuItem(const AxRangeMenuItem& item) { Copy(item); }
    AxRangeMenuItem() {}
    AxRangeMenuItem(const wxString& label, const wxString& description,
        const wxString& id,
        int minValue,
        int maxValue,
        int value);
    bool Create(const wxString& label, const wxString& description,
        const wxString& id,
        int minValue,
        int maxValue,
        int value);

    void Copy(const AxRangeMenuItem& item);

    virtual AxMenuItem* Clone() { return new AxRangeMenuItem(* this); }

    void SetValue(int value);
    int GetValue() const { return m_value; }

    void SetMinValue(int minValue) { m_minValue = minValue;  }
    int GetMinValue() const { return m_minValue; }

    void SetMaxValue(int maxValue) { m_maxValue = maxValue;  }
    int GetMaxValue() const { return m_maxValue; }

    wxString CreateString(const wxString& spec, bool isLabel);

    void SendRangeUpdate(int value);

protected:
    int     m_minValue;
    int     m_maxValue;
    int     m_value;
};

/**
    @class AxRangeValidator
 */

class AxRangeValidator: public AxValidator
{
    DECLARE_DYNAMIC_CLASS( AxRangeValidator )

public:
// Constructors

    AxRangeValidator(const AxRangeValidator& validator) { Init(); Copy(validator); }
    AxRangeValidator(int* ptr) { Init(); m_intPtr = ptr; }
    AxRangeValidator() { Init(); }
    ~AxRangeValidator() {}

// Operations

    void Copy(const AxRangeValidator& validator)
    {
        AxValidator::Copy(validator);

        m_intPtr = validator.m_intPtr;
    }

    virtual AxValidator* Clone() const { return new AxRangeValidator(*this); }

    /// Override to pass a value from the UI to a data structure
    virtual bool TransferDataFromMenu();

    /// Override to pass a value from a data structure to the UI
    virtual bool TransferDataToMenu();

    /// Initialize variables
    void Init() { m_intPtr = NULL; }

protected:
    int*        m_intPtr;
};


#endif
    // _AX_MENU_RANGE_H_
